os.loadAPI('api/logf')
os.loadAPI('api/turtle_utils')

logf.setLogToConsole(false)
logf.LogFileName = "qm.log"

sorter = peripheral.wrap("back")

--print("Methods:")
--for k,v in pairs(peripheral.getMethods("bottom")) do
--	print("  * "..tostring(k)..": "..tostring(v))
--end
function len(tab)
	count = 0
	for _ in pairs(tab) do
		count = count + 1
	end
	return count
end

dir = {
	down=0,
	up=1,
	north=2,
	south=3,
	west=4,
	east=5
}

FURNACE_INPUT_SIDE = dir.up
FURNACE_FUEL_SIDE = dir.south
FURNACE_OUTPUT_SIDE = dir.south
STORAGE_SIDE = dir.north
INPUT_SIDE = dir.west
OUTPUT_SIDE = dir.down
SELF_SIDE = dir.east

function getUUID(id, meta)
  uuid = id + meta * 32768
  return uuid
end
 
function getID(uuid)
  id = uuid
  meta = 0
  if uuid > 32768 then
    meta = uuid%32768
    id = id - (meta * 32768)
  end
end

function create_item(items, id_, name_, item_type_)
	items[id_] = {
		id=id_,
		name=name_,
		item_type=item_type_
	}
	items[name_] = items[id_]
end

ITEM_TYPE_RAW = 0
ITEM_TYPE_COOKED = 1
ITEM_TYPE_CRAFTED = 2
items = {}
create_item(items, 1, "Stone", ITEM_TYPE_COOKED)
create_item(items, 4, "Cobblestone", ITEM_TYPE_RAW)
create_item(items, 5, "Wood Plank", ITEM_TYPE_CRAFTED)
create_item(items, 12, "Sand", ITEM_TYPE_RAW)
create_item(items, 14, "Gold Ore", ITEM_TYPE_RAW)
create_item(items, 15, "Iron Ore", ITEM_TYPE_RAW)
create_item(items, 17, "Wood Log", ITEM_TYPE_RAW)
create_item(items, 20, "Glass", ITEM_TYPE_COOKED)
create_item(items, 54, "Chest", ITEM_TYPE_CRAFTED)
create_item(items, 102, "Glass Pane", ITEM_TYPE_CRAFTED)
create_item(items, getUUID(263, 1), "Charcoal", ITEM_TYPE_RAW)
create_item(items, 264, "Diamond", ITEM_TYPE_RAW)
create_item(items, 265, "Iron Ingot", ITEM_TYPE_COOKED)
create_item(items, 266, "Gold Ingot", ITEM_TYPE_COOKED)
create_item(items, 278, "Diamond Pick", ITEM_TYPE_CRAFTED)
create_item(items, 280, "Stick", ITEM_TYPE_CRAFTED)
create_item(items, 331, "Redstone", ITEM_TYPE_RAW)
create_item(items, 1225, "Computer", ITEM_TYPE_CRAFTED)
create_item(items, 1227, "Turtle", ITEM_TYPE_CRAFTED)
create_item(items, getUUID(1227, 1), "Mining Turtle", ITEM_TYPE_CRAFTED)
--for k, v in pairs(items) do
--	print(tostring(k),": ", tostring(v.name))
--end

function new_material(item, required)
	return {
		item=item,
		required=required,
		stored=0
	}
end

materials = {
	[items["Cobblestone"].id]=new_material(items["Cobblestone"], 7),
	[items["Wood Plank"].id]=new_material(items["Wood Plank"], 10),
	[items["Stone"].id]=new_material(items["Stone"], 7),
	[items["Sand"].id]=new_material(items["Sand"], 6),
	[items["Iron Ore"].id]=new_material(items["Iron Ore"], 7),
	[items["Wood Log"].id]=new_material(items["Wood Log"], 3),
	[items["Glass"].id]=new_material(items["Glass"], 6),
	[items["Chest"].id]=new_material(items["Chest"], 1),
	[items["Glass Pane"].id]=new_material(items["Glass Pane"], 1),
	[items["Charcoal"].id]=new_material(items["Charcoal"], 3),
	[items["Diamond"].id]=new_material(items["Diamond"], 3),
	[items["Iron Ingot"].id]=new_material(items["Iron Ingot"], 7),
	[items["Diamond Pick"].id]=new_material(items["Diamond Pick"], 1),
	[items["Stick"].id]=new_material(items["Stick"], 2),
	[items["Redstone"].id]=new_material(items["Redstone"], 1),
	[items["Computer"].id]=new_material(items["Computer"], 1),
	[items["Turtle"].id]=new_material(items["Turtle"], 1),
	[items["Mining Turtle"].id]=new_material(items["Mining Turtle"], 1),
}

function new_cooking_material(source_item, source_item_amount, fuel_item, fuel_item_amount, dest_item, dest_item_amount)
	return {
		source_item=source_item,
		source_item_amount=source_item_amount,
		fuel_item=fuel_item,
		fuel_item_amount=fuel_item_amount,
		dest_item=dest_item,
		dest_item_amount=dest_item_amount
	}
end

cooking_materials = {
	new_cooking_material(items["Cobblestone"], 7, items["Charcoal"], 1, items["Stone"], 7),
	new_cooking_material(items["Sand"], 6, items["Charcoal"], 1, items["Glass"]),
	new_cooking_material(items["Iron Ore"], 7, items["Charcoal"], 1, items["Iron Ingot"], 7)
}

function new_craft(item, required)
	return {
		item=item,
		required=required
	}
end

crafts = new_craft(items["Mining Turtle"], {
		new_craft(items["Diamond Pick"], {
			new_craft(items["Stick"], {
				new_craft(items["Wood Plank"], {
					new_craft(items["Wood Log"], {})
				})
			}),
			new_craft(items["Diamond"], {})
		}),
		new_craft(items["Turtle"], {
			new_craft(items["Computer"], {
				new_craft(items["Stone"], {
					new_craft(items["Cobblestone"], {})
				}),
				new_craft(items["Redstone"], {}),
				new_craft(items["Glass Pane"], {
					new_craft(items["Glass"], {
						new_craft(items["Sand"], {})
					})
				})
			}),
			new_craft(items["Chest"], {
				new_craft(items["Wood Plank"], {
					new_craft(items["Wood Log"], {})
				})
			}),
			new_craft(items["Iron Ingot"], {
				new_craft(items["Iron Ore"], {})
			})
		})
	})

--print("Listing side south:")
--for uuid, count in pairs(sorter.list(dir.south)) do
--	print(" * "..tostring(uuid)..": "..tostring(count))
--end

--sorter.sort(dir.up, 1)

--sorter.extract(dir.south, 1, dir.north, 1)
asd = false
crafting_timer = nil
cooking_timer = nil
function main()
	logf.logf(logf.INFO, "main", "Starting up")
	local cooking = init()
	
	local cookingCheck = false
	if not cooking then
		logf.logf(logf.INFO, "main", "No cooking items detected, waiting for confirmation")
		cookingCheck = true
		cooking_timer = os.startTimer(7)
	else
		logf.logf(logf.INFO, "main", "Cooking items detected")
		cooking_timer = os.startTimer(5)
	end
	sorter.sort(OUTPUT_SIDE)
	while true do
		printFrame()
		logf.logf(logf.DEBUG, "main", "Waiting for event")
		event, param1, param2 = os.pullEvent()
		logf.logf(logf.DEBUG, "main", "Event %s received with parameters (%s, %s)", event, tostring(param1), tostring(param2))
		if event == 'isort_item' then
			if asd or cookingCheck then
				addLog("ignoring item, waiting for cooking check")
				logf.logf(logf.INFO, "sorting", "Waiting for cooking check, sorting item to output")
				sorter.sort(OUTPUT_SIDE)
			else
				if cooking then
					addLog("we are cooking")
					logf.logf(logf.INFO, "sorting", "Cooking items, sorting item to output")
					sorter.sort(OUTPUT_SIDE)
				else
					onItemReceived(param1, param2)
				end
			end
		elseif event == 'timer' then
			if param1 == crafting_timer then
				logf.logf(logf.INFO, "crafting", "Crafting timer received")
				tryCraft(crafts)
				crafting_timer = nil
				sorter.sort(OUTPUT_SIDE)
			elseif param1 == cooking_timer then
				if cookingCheck then
					cooking = init()
					if cooking then
						cooking_timer = os.startTimer(5)
					else
						cooking_timer = nil
						crafting_timer = os.startTimer(4)
					end
					cookingCheck = false
					addLog("first time cooking check, result = "..tostring(cooking))
				else
					if isDoneCooking() then
						addLog("Done cooking")
						clearFurnace()
						cooking = false
						onFinishedCooking()
						cooking_timer = nil
						crafting_timer = os.startTimer(4)
					else
						cooking_timer = os.startTimer(5)
					end
				end
			end
		end
		printFrame()
	end
end

function init()
	logf.logf(logf.INFO, "main", "Initializing")
	storedInv = sorter.list(SELF_SIDE)
	if storedInv ~= nil then
		for itemUUID, amount in pairs(storedInv) do
			logf.logf(logf.DEBUG, "main", "Found %d of item %d in my inventory, moving to storage", amount, itemUUID)
			sorter.extract(SELF_SIDE, itemUUID, STORAGE_SIDE, amount)
		end
	else
		logf.logf(logf.DEBUG, "main", "Nothing found on my inventory")
	end
	
	storedInv = sorter.list(STORAGE_SIDE)
	if storedInv ~= nil then
		for itemUUID, amount in pairs(storedInv) do
			logf.logf(logf.DEBUG, "main", "Found %d of item %d in the storage inventory", amount, itemUUID)
			materials[itemUUID].stored = amount
		end
	else
		logf.logf(logf.DEBUG, "main", "Nothing found on the storage inventory")
	end
	
	storedInv = sorter.list(FURNACE_OUTPUT_SIDE)
	if storedInv ~= nil and len(storedInv) > 0 then
		logf.logf(logf.DEBUG, "main", "Items found on the furnace inventory")
		return true
	else
		logf.logf(logf.DEBUG, "main", "Nothing found on the furnace inventory")
		return false
	end
end

function isDoneCooking()
	storedInv = sorter.list(FURNACE_OUTPUT_SIDE)
	if storedInv ~= nil then
		for itemUUID, amount in pairs(storedInv) do
			if itemUUID == items["Cobblestone"].id or itemUUID == items["Sand"].id or itemUUID == items["Iron Ore"].id then
				return false
			end
		end
		return true
	else
		addLog("ERROR: should never have called finishedCooking() when there's no items in the furnace")
		return true
	end
end

function clearFurnace()
	storedInv = sorter.list(FURNACE_OUTPUT_SIDE)
	if storedInv ~= nil then
		for itemUUID, amount in pairs(storedInv) do
			sorter.extract(FURNACE_OUTPUT_SIDE, itemUUID, STORAGE_SIDE, amount)
			materials[itemUUID].stored = materials[itemUUID].stored + amount
			if itemUUID == items["Stone"].id then
				materials[items["Cobblestone"].id].stored = 0
			elseif itemUUID == items["Glass"].id then
				materials[items["Sand"].id].stored = 0
			elseif itemUUID == items["Iron Ingot"].id then
				materials[items["Iron Ore"].id].stored = 0
			end
		end
	end
end

function onItemReceived(itemUUID, amount)
	material = materials[itemUUID]
	if material == nil then
		addLog("unknown item")
		logf.logf(logf.DEBUG, "sorting", "Unknown item %d received, sorting it to output", itemUUID)
		sorter.sort(OUTPUT_SIDE)
	else
		amountNeeded = getAmountNeeded(material)
		logf.logf(logf.DEBUG, "sorting", "Received %d item %d (%s), need %d", amount, itemUUID, material.item.name, amountNeeded)
		if amountNeeded ~= 0 then
			if amountNeeded <= amount then
				addLog("storing "..tostring(amountNeeded).." of "..tostring(material.item.name))
				sorter.sort(STORAGE_SIDE, amountNeeded)
				material.stored = material.stored + amountNeeded
				sorter.sort(OUTPUT_SIDE)
			else
				addLog("storing "..tostring(amount).." of "..tostring(material.item.name))
				sorter.sort(STORAGE_SIDE, amount)
				material.stored = material.stored + amount
			end
		else
			addLog("No need for "..tostring(material.item.name))
			sorter.sort(OUTPUT_SIDE)
		end
		crafting_timer = os.startTimer(4)
		logf.logf(logf.DEBUG, "crafting", "Starting crafting timer (%d)", crafting_timer)
	end
end

function onFinishedCooking()
end

function getAmountNeeded(item)
	return searchCrafting(item, crafts)
end

function searchCrafting(material, craft)
	--addLog("searching ", item, " ", item.name, " ", craft.item)
	if material.item == craft.item then
		if material.stored > material.required then
			return 0
		else
			return material.required - material.stored
		end
	end
	if materials[craft.item.id].stored >= materials[craft.item.id].required then
		return 0
	end
	
	amount = 0
	for _,req in pairs(craft.required) do
		amount = amount + searchCrafting(material, req)
	end
	return amount
end

function tryCraft(craft)

	logf.logf(logf.DEBUG, "crafting", "trycraft %d (%s)", craft.item.id, craft.item.name)
	if materials[craft.item.id].stored >= materials[craft.item.id].required then
		logf.logf(logf.DEBUG, "crafting", "trycraft %d (%s) stored true", craft.item.id, craft.item.name)
		return true
	end
	
	if craft.item.item_type == ITEM_TYPE_CRAFTED then
		local complete = true
		for _,req in pairs(craft.required) do
			if materials[req.item.id].stored < materials[req.item.id].required then
				if not tryCraft(req) then
					complete = false
				end
			end
		end
		if complete then
			logf.logf(logf.DEBUG, "crafting", "Crafting item %d (%s)", craft.item.id, craft.item.name)
			doCraft(craft)
			
			return true
		end
		logf.logf(logf.DEBUG, "crafting", "trycraft %d (%s) sub items craft false", craft.item.id, craft.item.name)
		return false
	elseif craft.item.item_type == ITEM_TYPE_COOKED then
		if cooking_timer == nil then
			if materials[craft.required[1].item.id].stored >= materials[craft.required[1].item.id].required then
				logf.logf(logf.DEBUG, "crafting", "Cooking item %d (%s)", craft.item.id, craft.item.name)
				addLog("Cooking "..craft.item.name)
				sorter.extract(STORAGE_SIDE, craft.required[1].item.id, FURNACE_INPUT_SIDE, materials[craft.required[1].item.id].required)
				sorter.extract(STORAGE_SIDE, items["Charcoal"].id, FURNACE_FUEL_SIDE, 1)
				cooking_timer = os.startTimer(3)
			end
		end
		logf.logf(logf.DEBUG, "crafting", "trycraft %d (%s) cooking false", craft.item.id, craft.item.name)
		return false
	elseif craft.item.item_type == ITEM_TYPE_RAW then
		logf.logf(logf.DEBUG, "crafting", "trycraft %d (%s) raw false", craft.item.id, craft.item.name)
		return false
	end
end

function doCraft(craft)
	if craft.item.item_type == ITEM_TYPE_COOKED then
		addLog("need to cook")
		return false
	elseif craft.item.item_type == ITEM_TYPE_CRAFTED then
		if craft.item.name == "Wood Plank" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 3)
			turtle.craft()
			sorter.extract(SELF_SIDE, craft.item.id, STORAGE_SIDE, 12)
			materials[craft.item.id].stored = materials[craft.item.id].stored + 12
			materials[craft.required[1].item.id].stored = materials[craft.required[1].item.id].stored - 3
		elseif craft.item.name == "Chest" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 8)
			turtle.transferTo(2, 1)
			turtle.transferTo(3, 1)
			turtle.transferTo(5, 1)
			turtle.transferTo(7, 1)
			turtle.transferTo(9, 1)
			turtle.transferTo(10, 1)
			turtle.transferTo(11, 1)
			turtle.craft()
			sorter.extract(SELF_SIDE, craft.item.id, STORAGE_SIDE, 1)
			materials[craft.item.id].stored = materials[craft.item.id].stored + 1
			materials[craft.required[1].item.id].stored = materials[craft.required[1].item.id].stored - 8
		elseif craft.item.name == "Glass Pane" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 6)
			turtle.transferTo(2, 1)
			turtle.transferTo(3, 1)
			turtle.transferTo(5, 1)
			turtle.transferTo(6, 1)
			turtle.transferTo(7, 1)
			turtle.craft()
			sorter.extract(SELF_SIDE, craft.item.id, STORAGE_SIDE, 16)
			materials[craft.item.id].stored = materials[craft.item.id].stored + 16
			materials[craft.required[1].item.id].stored = materials[craft.required[1].item.id].stored - 6
		elseif craft.item.name == "Diamond Pick" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 2)
			turtle.transferTo(6, 1)
			turtle.transferTo(10, 1)
			sorter.extract(STORAGE_SIDE, craft.required[2].item.id, SELF_SIDE, 3)
			turtle.transferTo(2, 1)
			turtle.transferTo(3, 1)
			turtle.craft()
			sorter.extract(SELF_SIDE, craft.item.id, STORAGE_SIDE, 1)
			materials[craft.item.id].stored = materials[craft.item.id].stored + 1
			materials[craft.required[1].item.id].stored = materials[craft.required[1].item.id].stored - 2
			materials[craft.required[2].item.id].stored = materials[craft.required[2].item.id].stored - 3
		elseif craft.item.name == "Stick" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 2)
			turtle.transferTo(5, 1)
			turtle.craft()
			sorter.extract(SELF_SIDE, craft.item.id, STORAGE_SIDE, 4)
			materials[craft.item.id].stored = materials[craft.item.id].stored + 4
			materials[craft.required[1].item.id].stored = materials[craft.required[1].item.id].stored - 2
		elseif craft.item.name == "Computer" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[2].item.id, SELF_SIDE, 1)
			turtle.transferTo(6, 1)
			sorter.extract(STORAGE_SIDE, craft.required[3].item.id, SELF_SIDE, 1)
			turtle.transferTo(10, 1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 7)
			turtle.transferTo(2, 1)
			turtle.transferTo(3, 1)
			turtle.transferTo(5, 1)
			turtle.transferTo(7, 1)
			turtle.transferTo(9, 1)
			turtle.transferTo(11, 1)
			turtle.craft()
			sorter.extract(SELF_SIDE, craft.item.id, STORAGE_SIDE, 1)
			materials[craft.item.id].stored = materials[craft.item.id].stored + 1
			materials[craft.required[1].item.id].stored = materials[craft.required[1].item.id].stored - 7
			materials[craft.required[2].item.id].stored = materials[craft.required[2].item.id].stored - 1
			materials[craft.required[3].item.id].stored = materials[craft.required[3].item.id].stored - 1
		elseif craft.item.name == "Turtle" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[2].item.id, SELF_SIDE, 1)
			turtle.transferTo(10, 1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 1)
			turtle.transferTo(6, 1)
			sorter.extract(STORAGE_SIDE, craft.required[3].item.id, SELF_SIDE, 7)
			turtle.transferTo(2, 1)
			turtle.transferTo(3, 1)
			turtle.transferTo(5, 1)
			turtle.transferTo(7, 1)
			turtle.transferTo(9, 1)
			turtle.transferTo(11, 1)
			turtle.craft()
			sorter.extract(SELF_SIDE, craft.item.id, STORAGE_SIDE, 1)
			materials[craft.item.id].stored = materials[craft.item.id].stored + 1
			materials[craft.required[1].item.id].stored = materials[craft.required[1].item.id].stored - 1
			materials[craft.required[2].item.id].stored = materials[craft.required[2].item.id].stored - 1
			materials[craft.required[3].item.id].stored = materials[craft.required[3].item.id].stored - 7
		elseif craft.item.name == "Mining Turtle" then
			turtle.select(1)
			sorter.extract(STORAGE_SIDE, craft.required[1].item.id, SELF_SIDE, 1)
			turtle.transferTo(2, 1)
			sorter.extract(STORAGE_SIDE, craft.required[2].item.id, SELF_SIDE, 1)
			turtle.craft()
			turtle.place()
			os.sleep(3)
			miner = peripheral.wrap("front")
			miner.turnOn()
			print("turned on")
			os.sleep(5)
			shell.run('reboot')
		else
			addLog("Missing crafting for "..craft.item.name)
		end
		addLog("Crafted "..craft.item.name)
		return true
		--io.read()
	end
	return false
end

term.setCursorBlink(false)
local w, h = term.getSize()
logSize = h - 19
logMsgs = {}
for i=1, 2 do
	logMsgs[i] = ""
end
logEnd = nil
function printFrame()
	term.clear()
	term.setCursorPos(1, 1)
	local count = 0
	for k, v in pairs(materials) do
		count = count + 1
		if count > 9 then
			term.setCursorPos(22, count - 9)
		else
			term.setCursorPos(1, count)
		end
		--getAmountNeeded(v)
		print(string.format("%13s | %d/%d", v.item.name, v.stored, v.required))
	end
	term.setCursorPos(1, 10)
	print("---------------------------------------")
	term.setCursorPos(1, 11)
	for i=1, 2 do
		print(tostring(logMsgs[i]))
	end
end

function addLog(msg)
	logMsgs[2] = logMsgs[1]
	logMsgs[1] = msg
end	

function install_disk()
	if fs.exists('/disk/next_chunk') then
		fs.
		next_chunk = 1
	else
		local f = fs.open('/disk/next_chunk', 'r')
		next_chunk = tonumber(f.readAll())
		f.close()
	end

	if not fs.exists('/api') then
		fs.makeDir('/api')
	end
	if not fs.exists('/lib') then
		fs.makeDir('/lib')
	end
	if not fs.exists('/lib/status.lua') then
		fs.copy('/disk/lib/status.lua', '/lib/status.lua')
	end
	if not fs.exists('/lib/serialize.lua') then
		fs.copy('/disk/lib/serialize.lua', '/lib/serialize.lua')
	end
	if not fs.exists('/api/logf') then
		fs.copy('/disk/api/logf', '/api/logf')
	end
	if not fs.exists('/lib/state_machine.lua') then
		fs.copy('/disk/lib/state_machine.lua', '/lib/state_machine.lua')
	end
	if not fs.exists('/api/inventory') then
		fs.copy('/disk/api/inventory', '/api/inventory')
	end
	if not fs.exists('/api/turtle_utils') then
		fs.copy('/disk/api/turtle_utils', '/api/turtle_utils')
	end
	if not fs.exists('/mine3') then
		fs.copy('/disk/mine3', '/mine3')
	end

	startupFile = fs.open('/startup', 'w')
	startupFile.write('shell.run(\'mine3\')')
	startupFile.close()
end

arg = {...}
if (arg[1] == nil) then
	
	main()
elseif arg[1] == 'disarm' then

	storedInv = sorter.list(STORAGE_SIDE)
	if storedInv ~= nil then
		for itemUUID, amount in pairs(storedInv) do
			sorter.extract(STORAGE_SIDE, itemUUID, OUTPUT_SIDE, amount)
		end
	end
	

	turtle.turnRight()
	turtle_utils.forward(1, false)
	turtle.turnLeft()
	turtle.select(7)
	turtle.suck()
	turtle.select(6)
	turtle.dig()
	turtle.turnRight()
	turtle.turnRight()
	turtle.select(5)
	turtle.dig()
	turtle_utils.up(1, false)
	turtle.select(4)
	turtle.dig()
	turtle.turnRight()
	turtle_utils.forward(1, false)
	turtle.turnLeft()
	turtle.dig()
	turtle_utils.down(1, false)
	turtle.select(3)
	turtle.dig()
	turtle_utils.forward(1, false)
	turtle.turnRight()
	turtle.select(2)
	turtle.dig()
	turtle.turnLeft()
elseif arg[1] == 'deploy' then
	turtle.turnRight()
	turtle.select(2)
	turtle.place()
	turtle.select(4)
	turtle.placeUp()
	turtle_utils.back(1)
	turtle.placeUp()
	turtle.select(3)
	turtle.place()
	turtle.turnLeft()
	turtle_utils.back(1)
	turtle.select(5)
	turtle.place()
	turtle.turnLeft()
	turtle.turnLeft()
	turtle.select(6)
	turtle.place()
	turtle.select(7)
	turtle.drop()
	
	install_disk()
	
	turtle.turnLeft()
	turtle_utils.forward(1, false)
	turtle.turnRight()

elseif arg[1] == 'init' then
	print("initializing quarry master")
	print("Insert a piece of fuel into the interactive sorter")
	event, itemuuid, amount = os.pullEvent("isort_item")
	print(event.."setting the uuid "..tostring(itemuuid).." for the fuel")
	print("Insert a piece of iron ore into the interactive sorter")
	event, itemuuid, amount = os.pullEvent("isort_item")
	print(event.."setting the uuid "..tostring(itemuuid).." as iron ore")
	print("Insert a piece of cobblestone into the interactive sorter")
	event, itemuuid, amount = os.pullEvent("isort_item")
	print(event.."setting the uuid "..tostring(itemuuid).." as cobblestone")
else
	print("Listing side south:")
	for uuid, count in pairs(sorter.list(STORAGE_SIDE)) do
		print(" * "..tostring(uuid)..": "..tostring(count))
	end
	print("error: invalid parameter passed")
end
